package com.cx.common.redis.util;

import com.cx.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 基于redis全局唯一ID生成器
 * 优点：1.唯一（不必说了）
 * 2.单调递增（天然排序、分页优势）
 * 4.不依赖与关系型数据库，灵活方便。
 * 3.sql索引的查询效率，long类型的值比String的查询效率高。
 *
 * @author TH
 * @date 2022/3/24
 */
@Component
public class RedisIdGenerator {

    /**
     * 步长/变化数量：一般情况集群有多台redis那么有几台步长就设置多少
     */
    private final static long DELTA = 1L;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 生成外部订单号
     *
     * @return
     */
    public String getExternalOrder() {
        //当前时间- YYYYMMDDHHMMSS
        String s = "EX" + DateUtils.dateTimeNow();
        //获取key的时间规则 YYYY-MM-DD
        String key = "external:" + DateUtils.getDate();
        long count = stringRedisTemplate.opsForValue().increment(key, DELTA);
        stringRedisTemplate.expire(key, DateUtils.getLimitTime(), TimeUnit.MILLISECONDS);
        //3.拼接返回，外部订单标识SC+ YYYYMMDDHHMMSS + 6位数字。
        return s + String.format("%06d", count);
    }

    /**
     * 生成交易订单号
     *
     * @return
     */
    public String getTradingOrder() {
        //当前时间- YYYYMMDDHHMMSS
        String s = "TR" + DateUtils.dateTimeNow();
        //获取key的时间规则 YYYY-MM-DD
        String key = "trade:" + DateUtils.getDate();
        long count = stringRedisTemplate.opsForValue().increment(key, DELTA);
        stringRedisTemplate.expire(key, DateUtils.getLimitTime(), TimeUnit.MILLISECONDS);
        //3.拼接返回，交易订单标识TO+ YYYYMMDDHHMMSS + 6位数字。
        return s + String.format("%06d", count);
    }

    /**
     * 生成挂单订单号
     *
     * @return
     */
    public String getPendingOrder() {
        //当前时间- YYYYMMDDHHMMSS
        String s = "PE" + DateUtils.dateTimeNow();
        //获取key的时间规则 YYYY-MM-DD
        String key = "pend:" + DateUtils.getDate();
        long count = stringRedisTemplate.opsForValue().increment(key, DELTA);
        stringRedisTemplate.expire(key, DateUtils.getLimitTime(), TimeUnit.MILLISECONDS);
        //3.拼接返回，挂单订单标识SC+ YYYYMMDDHHMMSS + 6位数字。
        return s + String.format("%06d", count);
    }


}

